package com.linfeng.api.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.linfeng.api.param.LoginParam;
import com.linfeng.api.param.VerityParam;
import com.linfeng.api.redis.util.RedisUtils;
import com.linfeng.api.service.TrymallUserService;
import com.linfeng.api.util.jwt.JwtToken;
import com.linfeng.api.util.sms.SmsUtils;
import com.linfeng.common.constant.ShopConstants;
import com.linfeng.common.domain.TrymallUser;
import com.linfeng.common.enums.ShopCommonEnum;
import com.linfeng.common.enums.SmsTypeEnum;
import com.linfeng.common.exception.TrymallException;
import com.linfeng.common.response.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author linfeng
 * @date 2020/8/30 21:20
 */
@RestController
public class AuthController {

    @Autowired
    private TrymallUserService trymallUserService;
    @Autowired
    private RedisUtils redisUtil;

    /**
     * 账号密码登录
     * @param loginParam
     * @param request
     * @return
     */
    @PostMapping(value = "/user/userlogin")
    public ApiResult<Map<String, Object>> login(@Validated @RequestBody LoginParam loginParam, HttpServletRequest request) {
        TrymallUser user = trymallUserService.getOne(Wrappers.<TrymallUser>lambdaQuery()
                .eq(TrymallUser::getUsername, loginParam.getUsername())
                .eq(TrymallUser::getPassword, SecureUtil.md5(loginParam.getPassword())), false);
        if(user == null){
            throw new TrymallException(ShopConstants.USER_LOGIN_REFUSE);
        }
        String token =  JwtToken.makeToken(user.getUid());
        String expiresTimeString = JwtToken.getExpireTime(token);
        Map<String, Object> map = new HashMap<String, Object>(2) {{
            put("token", token);
            put("expires_time", expiresTimeString);
        }};

        return ApiResult.ok(map).setMsg(ShopConstants.LOGIN_SUCCESS);
    }

    /**
     * 短信验证登录
     * @param param
     * @return
     */
    @PostMapping("/sms/verify")
    public ApiResult<String> verify(@Validated @RequestBody VerityParam param) {
        TrymallUser user = trymallUserService.getOne(Wrappers.<TrymallUser>lambdaQuery()
                .eq(TrymallUser::getPhone,param.getPhone()),false);
        if (SmsTypeEnum.REGISTER.getValue().equals(param.getType()) && ObjectUtil.isNotNull(user)) {
            return ApiResult.fail(ShopConstants.PHONE_REGISTER);
        }
        if (SmsTypeEnum.LOGIN.getValue().equals(param.getType()) && ObjectUtil.isNull(user)) {
            return ApiResult.fail(ShopConstants.ACCOUNT_NOT_EXIST);
        }
        String enable = redisUtil.getY("sms_enable");
        String codeKey = "code_" + param.getPhone();
        if (ObjectUtil.isNotNull(redisUtil.get(codeKey))) {
            if (ShopCommonEnum.ENABLE_2.getValue().toString().equals(enable)) {
                return ApiResult.fail(ShopConstants.CODE_TIME + redisUtil.get(codeKey).toString());
            }
            return ApiResult.fail(ShopConstants.CODE_TIMES);
        }
        String code = RandomUtil.randomNumbers(ShopConstants.SMS_SIZE);
        //redis存储
        redisUtil.set(codeKey, code, ShopConstants.SMS_REDIS_TIME);

        if (ShopCommonEnum.ENABLE_2.getValue().toString().equals(enable)) {
            return ApiResult.fail(ShopConstants.CODE_TEST_VALUE + code);
        }
        //发送阿里云短信
        JSONObject json = new JSONObject();
        json.put("code",code);
        try {
            SmsUtils.sendSms(param.getPhone(),json.toJSONString());
        } catch (ClientException e) {
            redisUtil.del(codeKey);
            e.printStackTrace();
            return ApiResult.ok(ShopConstants.CODE_SEND_FAIL+e.getErrMsg());
        }
        return ApiResult.ok(ShopConstants.CODE_SEND_SUCCESS);

    }



}
